/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 * Description: util head file
 */
#ifndef UTIL_H
#define UTIL_H

#include <opencv2/core/core.hpp>
#include <opencv2/core/utils/filesystem.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <vector>
#include <iostream>
#include <chrono>  // chrono::system_clock
#include <ctime>   // localtime
#include <sstream> // stringstream
#include <iomanip> // put_time
#include <string>  // string
#include <sys/stat.h>
#include "yaml/haf_yaml.h"

constexpr int CNF1 = -1;
constexpr int CN1 = 1;
constexpr int CN2 = 2;
constexpr int CN3 = 3;
constexpr int CN4 = 4;
constexpr int CN5 = 5;
constexpr int CN6 = 6;
constexpr int CN7 = 7;
constexpr int CN8 = 8;
constexpr int CN10 = 10;
constexpr int CN15 = 15;
constexpr int CN16 = 16;
constexpr int CN20 = 20;
constexpr int CN21 = 21;
constexpr int CN24 = 24;
constexpr int CN30 = 30;
constexpr int CN31 = 31;
constexpr int CN32 = 32;
constexpr int CN33 = 33;
constexpr int CN34 = 34;
constexpr int CN39 = 39;
constexpr int CN40 = 40;
constexpr int CN41 = 41;
constexpr int CN60 = 60;
constexpr int CN96 = 96;
constexpr int CN99 = 99;
constexpr int CN100 = 100;
constexpr int CN103 = 103;
constexpr int CN107 = 107;
constexpr int CN112 = 112;
constexpr int CN128 = 128;
constexpr int CN500 = 500;
constexpr int CN1000 = 1000;
constexpr int CN1021 = 1021;
constexpr int CN1034 = 1034;
constexpr int CN1856 = 1856;
constexpr int CN2880 = 2880;
constexpr int CN4096 = 4096;
constexpr int CN100002 = 100002;
constexpr int CN100037 = 100037;
constexpr int CN1000000 = 1000000;
constexpr int CN5000000 = 5000000;

constexpr int32_t half = 2;
constexpr int32_t resolutionSize = 4;
constexpr int32_t sliceSize = 7400000;

constexpr float CN1P5 = 1.5;

extern int g_switchFlagTWO;
extern int g_switchFlag;
extern void ClearSwitchFlag();
extern int g_imageVideoFlag;
void ResetImageVideoFlag();

std::string CurrentTimeAndDate();

void Yuv420p2nv12(const cv::Mat &yuv420p, cv::Mat &yuv420_nv12, int32_t width, int32_t height);
int32_t getFiles(std::string &path, std::vector<std::string> &files, std::string suffix);
int32_t getFilesBySort(std::string &path, std::vector<std::string> &files, std::string suffix);
time_t convertTimeStr2TimeStamp(std::string timeStr);

class FuncTimeMeasure {
public:
    explicit FuncTimeMeasure(std::string &&descrip);
    ~FuncTimeMeasure();

private:
    std::string description;
    std::chrono::time_point<std::chrono::steady_clock> start {};
    std::chrono::time_point<std::chrono::steady_clock> end {};
};

struct Config {
    std::string dir { "" };
    int32_t instanceId { 0 };
    int32_t width { 0 };
    int32_t height { 0 };
};

class ConfigMangage {
public:
    ConfigMangage() = default;
    ~ConfigMangage() = default;
    explicit ConfigMangage(std::string configFile) : file(configFile) {}
    void Parse();
    std::vector<Config> GetConfig();
    void Show();
    bool CheckConfig();

    inline static bool FileExist(const std::string &name)
    {
        struct stat buffer;
        return (stat(name.c_str(), &buffer) == 0);
    }

private:
    std::string file { "image_config.yaml" };
    std::vector<Config> configs;
};

#endif // UTIL_H
